v->arch.hvm_svm.vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3;
}
+static void svm_update_vtpr(struct vcpu *v, unsigned long value)
+{
+ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+
+ vmcb->vintr.fields.tpr = value & 0x0f;
+}
+
unsigned long svm_get_ctrl_reg(struct vcpu *v, unsigned int num)
{
switch ( num )
hvm_funcs.update_host_cr3 = svm_update_host_cr3;
hvm_funcs.update_guest_cr3 = svm_update_guest_cr3;
+ hvm_funcs.update_vtpr = svm_update_vtpr;
+
hvm_funcs.stts = svm_stts;
hvm_funcs.set_tsc_offset = svm_set_tsc_offset;
case 8:
vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
+ vmcb->vintr.fields.tpr = value & 0x0F;
break;
default:
{
case APIC_TASKPRI:
vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
+ hvm_update_vtpr(v, (val >> 4) & 0x0f);
break;
case APIC_EOI:
v->arch.hvm_vmx.cpu_cr2 = cr2;
}
+static void vmx_update_vtpr(struct vcpu *v, unsigned long value)
+{
+ /* VMX doesn't have a V_TPR field */
+}
+
/* Setup HVM interfaces */
static void vmx_setup_hvm_funcs(void)
{
hvm_funcs.update_host_cr3 = vmx_update_host_cr3;
hvm_funcs.update_guest_cr3 = vmx_update_guest_cr3;
+ hvm_funcs.update_vtpr = vmx_update_vtpr;
+
hvm_funcs.stts = vmx_stts;
hvm_funcs.set_tsc_offset = vmx_set_tsc_offset;
*/
void (*update_guest_cr3)(struct vcpu *v);
+ /*
+ * Reflect the virtual APIC's value in the guest's V_TPR register
+ */
+ void (*update_vtpr)(struct vcpu *v, unsigned long value);
+
/*
* Update specifics of the guest state:
* 1) TS bit in guest cr0
hvm_funcs.update_host_cr3(v);
}
+static inline void
+hvm_update_vtpr(struct vcpu *v, unsigned long value)
+{
+ hvm_funcs.update_vtpr(v, value);
+}
+
void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3);
void hvm_hypercall_page_initialise(struct domain *d,